package com.example.common;
import com.example.dto.ThreadPoolChange;
import com.example.dto.ThreadPoolInfo;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.stream.Collectors;
/*
@description:线程池管理器
@ClassName ThreadPoolManager
@author chen
@create 2025-07-04 14:35
@Version 1.0
*/
public class ThreadPoolManager
{
    private static final Map<String, ThreadPoolTaskExecutor> threadPoolMap = new ConcurrentHashMap<>(16);

    private static final int keepAliveSeconds = 60;


    /*
     * @param name   线程池名称
     * @==============History===============<br/>;
     * @Description //   创建新的线程池,如果线程池已经创建,返回已经创建的线程池
     * @Date 2025/7/4
     */
    public static ThreadPoolTaskExecutor newThreadPool(String name)
    {
        int maxPoolSize = Integer.MAX_VALUE;
        int corePoolSize = 1;
        return newThreadPool(name, corePoolSize, maxPoolSize);
    }




    /*
     * @param name             线程池名称
     * @param corePoolSize     核心线程数
     * @param maxPoolSize      最大线程数
     * @==============History===============<br/>;
     * @Description //
     * @Date 2025/7/4
     * @Author < a href="chencheng@prmt.net">chen</ a>;
     */
    public static ThreadPoolTaskExecutor newThreadPool(String name, int corePoolSize, int maxPoolSize)
    {
        int queueCapacity = Integer.MAX_VALUE;
        return newThreadPool(name, corePoolSize, maxPoolSize, queueCapacity, keepAliveSeconds, null, null);
    }

    /*
     * @param name             线程池名称
     * @param corePoolSize     核心线程数
     * @param maxPoolSize      最大线程数
     * @param queueCapacity    队列大小
     * @==============History===============<br/>;
     * @Description //
     * @Date 2025/7/4
     */
    public static ThreadPoolTaskExecutor newThreadPool(String name, int corePoolSize, int maxPoolSize, int queueCapacity)
    {
        return newThreadPool(name, corePoolSize, maxPoolSize, queueCapacity, keepAliveSeconds, null, null);
    }

    /*
     * @param name                             线程池名称
     * @param corePoolSize                     核心线程数
     * @param maxPoolSize                      最大线程数
     * @param queueCapacity                    队列大小
     * @param keepAliveSeconds                 线程池存活时间（秒）
     * @param threadFactory                    线程工厂
     * @param rejectedExecutionHandler         拒绝策略
     * @==============History===============<br/>;
     * @Description //
     * @Date 2025/7/4
     */
    public static ThreadPoolTaskExecutor newThreadPool(String name,
                                                       int corePoolSize,
                                                       int maxPoolSize,
                                                       int queueCapacity,
                                                       int keepAliveSeconds,
                                                       ThreadFactory threadFactory,
                                                       RejectedExecutionHandler rejectedExecutionHandler)
    {
        return threadPoolMap.computeIfAbsent(name, threadGroupName ->
        {
            ThreadPoolTaskExecutor threadPoolExecutor = new ThreadPoolTaskExecutor()
            {
                private boolean initialized = false;
                @Override
                protected BlockingQueue<Runnable> createQueue(int queueCapacity)
                {
                    if(queueCapacity > 0)
                               return new ResizeLinkedBlockingQueue<>(queueCapacity);
                       return new SynchronousQueue<>();
                }

                @Override
                public void setQueueCapacity(int queueCapacity)
                {
                    if (this.initialized) {
                        this.getThreadPoolExecutor();
                        if (this.getThreadPoolExecutor().getQueue() != null && this.getThreadPoolExecutor().getQueue() instanceof ResizeLinkedBlockingQueue)
                        {
                            ((ResizeLinkedBlockingQueue<?>) this.getThreadPoolExecutor().getQueue()).setCapacity(queueCapacity);
                        }
                    }
                    super.setQueueCapacity(queueCapacity);
                }

                @Override
                public void afterPropertiesSet()
                {
                     if(initialized) return;
                     super.afterPropertiesSet();
                     this.initialized = true;
                }
            };
            threadPoolExecutor.setCorePoolSize(corePoolSize);
            threadPoolExecutor.setMaxPoolSize(maxPoolSize);
            threadPoolExecutor.setQueueCapacity(queueCapacity);
            threadPoolExecutor.setKeepAliveSeconds(keepAliveSeconds);
            threadPoolExecutor.setThreadGroupName(name);
            threadPoolExecutor.setThreadNamePrefix(name + "-");
            if (threadFactory != null)
            {
                threadPoolExecutor.setThreadFactory(threadFactory);
            }
            if (rejectedExecutionHandler != null)
            {
                threadPoolExecutor.setRejectedExecutionHandler(rejectedExecutionHandler);
            }
            threadPoolExecutor.afterPropertiesSet();
            return threadPoolExecutor;
        });
    }



    /*
     * @param
     * @==============History===============<br/>;
     * @Description //   获取所有线程池信息
     * @Date 2025/7/4
     */
    public static List<ThreadPoolInfo> threadPoolInfoList()
    {
        return threadPoolMap
                .entrySet()
                .stream()
                .map(entry -> threadPoolInfo(entry.getKey(), entry.getValue()))
                .collect(Collectors.toList());
    }


    /*
     * @param threadPool
     * @==============History===============<br/>;
     * @Description //   获取线程池的信息
     * @Date 2025/7/4
     */
    private static ThreadPoolInfo threadPoolInfo(String name, ThreadPoolTaskExecutor threadPool)
    {
        ThreadPoolInfo threadPoolInfo = new ThreadPoolInfo();
        threadPoolInfo.setName(name);
        threadPoolInfo.setCorePoolSize(threadPool.getCorePoolSize());
        threadPoolInfo.setMaxPoolSize(threadPool.getMaxPoolSize());
        threadPoolInfo.setActiveCount(threadPool.getActiveCount());
        threadPoolInfo.setQueueCapacity(threadPool.getQueueCapacity());
        threadPoolInfo.setQueueSize(threadPool.getQueueSize());
        return threadPoolInfo;
    }

    /*
     * @param threadPoolChange
     * @==============History===============<br/>;
     * @Description //   动态变更线程池
     * @Date 2025/7/8
     */
    public static void changeThreadPool(ThreadPoolChange threadPoolChange)
    {
        ThreadPoolTaskExecutor threadPoolTaskExecutor = threadPoolMap.get(threadPoolChange.getName());

        if (threadPoolTaskExecutor == null)
        {
            throw new IllegalArgumentException();
        }

        if (threadPoolChange.getCorePoolSize() > threadPoolChange.getMaxPoolSize())
        {
            throw new IllegalArgumentException();
        }

        synchronized (ThreadPoolManager.class)
        {
            if (threadPoolChange.getMaxPoolSize() > threadPoolTaskExecutor.getCorePoolSize())
            {
                threadPoolTaskExecutor.setMaxPoolSize(threadPoolChange.getMaxPoolSize());
                threadPoolTaskExecutor.setCorePoolSize(threadPoolChange.getCorePoolSize());
                threadPoolTaskExecutor.setQueueCapacity(threadPoolChange.getQueueCapacity());
            } else {
                threadPoolTaskExecutor.setCorePoolSize(threadPoolChange.getCorePoolSize());
                threadPoolTaskExecutor.setMaxPoolSize(threadPoolChange.getMaxPoolSize());
                threadPoolTaskExecutor.setQueueCapacity(threadPoolChange.getQueueCapacity());
            }
        }

    }
}
